package com.qunchuang.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

import static com.qunchuang.netty.Client.CHANNEL;
@ComponentScan
@Component
@Slf4j
@RequiredArgsConstructor
public class ReconnectClient {
    private final  ServerHandlerInit inits;

    public  void connect(int port, String host, String liftId) throws Exception{

        /**
         * 客户端的NIO线程组
         *
         */
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            /**
             * Bootstrap 是一个启动NIO服务的辅助启动类 客户端的
             */
            Bootstrap bootstrap = new Bootstrap();
            /**
             * 设置group
             */
            bootstrap = bootstrap.group(group);
            /**
             * 关联客户端通道
             */
            bootstrap = bootstrap.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);
            /**
             * 设置 I/O处理类,主要用于网络I/O事件，记录日志，编码、解码消息
             */
            bootstrap = bootstrap.handler(inits);

            System.out.println("netty client start success!");
            log.info("ReconnectClient连接成功");
            /**
             * 连接服务端
             */
            ChannelFuture f = bootstrap.connect(host, port).sync();
            CHANNEL.put(liftId,f);
            log.info("连接tcp添加数据{}",CHANNEL.get(liftId));
//            Map<ChannelId,String> I = new HashMap<>();
//            Map<String, ChannelFuture> O = new  HashMap<>();
//            f.channel().writeAndFlush()
            Channel channel = f.channel();
//            ChannelId channelId = channel.id();
//            ByteBuf buffer = Unpooled.buffer(10);
//            buffer.writeByte(0xaa);
//            buffer.writeByte(0x09);
//            buffer.writeByte(0x00);
//            buffer.writeByte(0x00);
//            buffer.writeByte(0x40);
//            buffer.writeByte(0x00);
//            buffer.writeByte(0x00);
//            buffer.writeByte(0x00);
//            buffer.writeByte(0x49);
//            buffer.writeByte(0xbb);
//            log.info("发送命令：{}",buffer);
//            ChannelFuture channelFuture = channel.writeAndFlush(buffer);

//            System.out.println("发送命令：" + channelFuture);
//            System.out.println("ChannelId: " + channelId);
            //通常需要写不断重连服务端
            f.addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess()) {
                    //重连交给后端线程执行
                    future.channel().eventLoop().schedule(() -> {
                        log.info("重连服务端...");
                        try {
                            log.info("再次执行连接");
                            connect(port,host,liftId);
                        } catch (Exception e) {
                            //                        e.printStackTrace();
                            log.error("连接失败。。。");
                        }
                    }, 3000, TimeUnit.MILLISECONDS);
                } else {
                    log.info("服务端连接成功...");
                }
            });
            /**
             * 等待连接端口关闭
             */
//            f.channel().closeFuture().sync();

        } finally {
            /**
             * 退出，释放资源
             */
//            group.shutdownGracefully();
        }
    }

}
